import type { VueKey, VueText } from '#/types'
import type { SortOrder } from 'ant-design-vue/es/table/interface'
import type {
  ActionType,
  Bordered,
  BorderedType,
  ProColumns,
  ProColumnType,
  UseFetchDataAction
} from '../typing'
import type { TablePaginationConfig } from 'ant-design-vue'
import type { IntlType } from '#/provider'
import { arrayMoveImmutable } from '#/utils/array-move'
import type { Ref } from 'vue'

/**
 * 合并用户 props 和 预设的 props
 */
export function mergePagination<T>(
  pagination: TablePaginationConfig | boolean | undefined,
  pageInfo: UseFetchDataAction<T>['pageInfo'] & {
    setPageInfo: any
  },
  intl: IntlType
): TablePaginationConfig | false | undefined {
  if (pagination === false) {
    return false
  }
  const { total, current, pageSize, setPageInfo } = pageInfo
  const defaultPagination: TablePaginationConfig = typeof pagination === 'object' ? pagination : {}

  return {
    showTotal: (all, range) =>
      `${intl.getMessage('pagination.total.range', '第')} ${range[0]}-${range[1]} ${intl.getMessage(
        'pagination.total.total',
        '条/总共'
      )} ${all} ${intl.getMessage('pagination.total.item', '条')}`,
    total,
    ...(defaultPagination as TablePaginationConfig),
    current,
    pageSize,
    showSizeChanger: true,
    onChange: (page: number, newPageSize?: number) => {
      const { onChange } = pagination as TablePaginationConfig
      onChange?.(page, newPageSize || 10)
      // pageSize 改变之后就没必要切换页码
      if (newPageSize !== pageSize || current !== page) {
        setPageInfo({ pageSize: newPageSize, current: page })
      }
    }
  }
}

/**
 * 获取用户的 action 信息
 */
export function useActionType<T>(
  ref: Ref<ActionType | undefined>,
  action: UseFetchDataAction<T>,
  props: {
    fullScreen: () => void
    onCleanSelected: () => void
    resetAll: () => void
    editableUtils: any
  }
) {
  /** 这里生成action的映射，保证 action 总是使用的最新 只需要渲染一次即可 */
  const userAction: ActionType = {
    ...props.editableUtils,
    pageInfo: action.pageInfo,
    reload: async (resetPageIndex?: boolean) => {
      // 如果为 true，回到第一页
      if (resetPageIndex) {
        await action.setPageInfo({
          current: 1
        })
      }
      action?.reload()
    },
    reloadAndRest: async () => {
      // reload 之后大概率会切换数据，清空一下选择。
      props.onCleanSelected()
      await action.setPageInfo({
        current: 1
      })
      await action?.reload()
    },
    reset: async () => {
      await props.resetAll()
      await action?.reset?.()
      await action?.reload()
    },
    fullScreen: () => props.fullScreen(),
    clearSelected: () => props.onCleanSelected(),
    // @ts-ignore
    setPageInfo: rest => action.setPageInfo(rest)
  }
  ref.value = userAction
}

type PostDataType<T> = (data: T) => T

/**
 * 一个转化的 pipeline 列表
 *
 * @param data
 * @param pipeline
 */
export function postDataPipeline<T>(data: T, pipeline: PostDataType<T>[]) {
  if (pipeline.filter(item => item).length < 1) {
    return data
  }
  return pipeline.reduce((pre, postData) => {
    return postData(pre)
  }, data)
}

export const isBordered = (borderType: BorderedType, border?: Bordered) => {
  if (border === undefined) {
    return false
  }
  // debugger
  if (typeof border === 'boolean') {
    return border
  }
  return border[borderType]
}

export const isMergeCell = (
  dom: any // 如果是合并单元格的，直接返回对象
) => dom && typeof dom === 'object' && dom?.props?.colSpan

/**
 * 根据 key 和 dataIndex 生成唯一 id
 *
 * @param key 用户设置的 key
 * @param index 序列号，理论上唯一
 */
export const genColumnKey = (key?: VueKey | undefined, index?: number): string => {
  if (key) {
    return Array.isArray(key) ? key.join('-') : key.toString()
  }
  return `${index}`
}

/**
 * 将 ProTable - column - dataIndex 转为字符串形式
 *
 * @param dataIndex Column 中的 dataIndex
 */
function parseDataIndex(dataIndex: ProColumnType['dataIndex']): string | undefined {
  if (Array.isArray(dataIndex)) {
    return dataIndex.join(',')
  }
  return dataIndex?.toString()
}

/**
 * 从 ProColumns 数组中取出默认的排序和筛选数据
 *
 * @param columns ProColumns
 */
export function parseDefaultColumnConfig<T, Value>(columns: ProColumns<T, Value>[]) {
  const filter: Record<string, VueText[] | null> = {}
  const sort: Record<string, SortOrder> = {}
  columns.forEach(column => {
    // 转换 dataIndex
    const dataIndex = parseDataIndex(column.dataIndex)
    if (!dataIndex) {
      return
    }
    // 当 column 启用 filters 功能时，取出默认的筛选值
    if (column.filters) {
      const defaultFilteredValue = column.defaultFilteredValue as VueText[]
      if (defaultFilteredValue === undefined) {
        filter[dataIndex] = null
      } else {
        filter[dataIndex] = column.defaultFilteredValue as VueText[]
      }
    }
    // 当 column 启用 sorter 功能时，取出默认的排序值
    if (column.sorter && column.defaultSortOrder) {
      sort[dataIndex] = column.defaultSortOrder!
    }
  })
  return { sort, filter }
}

export type SortDataParams = { oldIndex: number; newIndex: number }

/**
 * 数据排序核心逻辑
 *
 * @param oldIndex 原始位置
 * @param newIndex 新位置
 * @param data 原始数组
 */
export function sortData<T>({ oldIndex, newIndex }: SortDataParams, data: T[]): T[] | null {
  if (oldIndex !== newIndex) {
    const newData = arrayMoveImmutable([...(data || [])], oldIndex, newIndex).filter(el => !!el)
    return [...newData]
  }
  return null
}
